package com.dongdong.bookstore.module.ums.service.impl;

import cn.hutool.core.collection.CollUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.ArrayUtils;
import com.dongdong.bookstore.common.exception.Asserts;
import com.dongdong.bookstore.module.ums.mapper.MenuMapper;
import com.dongdong.bookstore.module.ums.mapper.ResourceMapper;
import com.dongdong.bookstore.module.ums.model.*;
import com.dongdong.bookstore.module.ums.mapper.RoleMapper;
import com.dongdong.bookstore.module.ums.service.*;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.dongdong.bookstore.module.ums.viewmodel.RoleParam;
import net.bytebuddy.agent.builder.AgentBuilder;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * <p>
 * 角色表 服务实现类
 * </p>
 *
 * @author chiangkai
 * @since 2021-10-20
 */
@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {

    @Autowired
    private UmsCacheService umsCacheService;

    @Autowired
    private RoleMapper roleMapper;

    @Autowired
    private MenuMapper menuMapper;

    @Autowired
    private ResourceMapper resourceMapper;

    @Autowired
    private AdminRoleRelationService adminRoleRelationService;

    @Autowired
    private RoleMenuRelationService roleMenuRelationService;
    @Autowired
    private RoleResourceRelationService roleResourceRelationService;

    @Override
    public List<Role> getLoleListByAdminId(Long adminId) {
        return roleMapper.getLoleListByAdminId(adminId);
    }

    @Override
    public void updateRole(Long adminId, List<Long> roleIds) {
        //删除原有关系
        QueryWrapper<AdminRoleRelation> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(AdminRoleRelation::getAdminId, adminId);
        adminRoleRelationService.remove(wrapper);
        if (CollUtil.isNotEmpty(roleIds)) {
            List<AdminRoleRelation> list = new ArrayList<>();
            for (Long roleId : roleIds) {
                AdminRoleRelation roleRelation = new AdminRoleRelation();
                roleRelation.setAdminId(adminId);
                roleRelation.setRoleId(roleId);
                list.add(roleRelation);
            }
            adminRoleRelationService.saveBatch(list);
            //更新各角色当前人数
            roleMapper.updateRoleCount();
        }
        umsCacheService.delResourceList(adminId);
    }

    @Override
    public void create(RoleParam roleParam) {
        Role role = new Role();
        BeanUtils.copyProperties(roleParam, role);
        Asserts.isFalse(save(role), "添加角色失败");
    }

    @Override
    public void update(Long id, RoleParam roleParam) {
        Role roleSource = getById(new Role().setId(id));
        Asserts.isNull(roleSource, "角色不存在");
        BeanUtils.copyProperties(roleParam, roleSource);
        Asserts.isFalse(updateById(roleSource), "更新失败");
    }

    @Override
    public boolean delete(List<Long> ids) {
        boolean b = removeByIds(ids);
        umsCacheService.delResourceListByRoleIds(ids);
        return b;
    }

    @Override
    public boolean updateStateById(Long id, Integer status) {
        Role role = new Role().setId(id).setStatus(status);
        boolean success = updateById(role);
        umsCacheService.delResourceListByRoleIds(Stream.of(id).collect(Collectors.toList()));
        return success;
    }

    /**
     * 通过角色ID获取角色拥有菜单
     *
     * @param roleId 角色ID
     * @return  角色菜单列表
     */
    @Override
    public List<Menu> menuListByRoleId(Long roleId) {
        return menuMapper.getMenuByRoleId(roleId);
    }

    /**
     * 通过角色Id获取资源列表
     *
     * @param roleId  角色ID
     * @return 资源列表
     */
    @Override
    public List<Resource> resourceListByRoleId(Long roleId) {
        return resourceMapper.getResouceListByRoleId(roleId);
    }

    @Override
    public void allocateMenu(Long roleId, List<Long> menuIds) {
        //先删除原有关系
        QueryWrapper<RoleMenuRelation> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(RoleMenuRelation::getRoleId, roleId);
        roleMenuRelationService.remove(wrapper);
        //批量插入新关系
        List<RoleMenuRelation> relationList = new ArrayList<>();
        for (Long menuId : menuIds) {
            RoleMenuRelation relation = new RoleMenuRelation();
            relation.setRoleId(roleId);
            relation.setMenuId(menuId);
            relationList.add(relation);
        }
        boolean saveBatch = roleMenuRelationService.saveBatch(relationList);
        Asserts.isFalse(saveBatch, "分配菜单失败");
        umsCacheService.clearMenuListAll();
    }

    @Override
    public void allocateResource(Long roleId, List<Long> resourceIds) {
        //先删除原有关系
        QueryWrapper<RoleResourceRelation> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(RoleResourceRelation::getRoleId, roleId);
        roleResourceRelationService.remove(wrapper);
        //批量插入新关系
        List<RoleResourceRelation> relationList = new ArrayList<>();
        for (Long resourceId : resourceIds) {
            RoleResourceRelation relation = new RoleResourceRelation();
            relation.setRoleId(roleId);
            relation.setResourceId(resourceId);
            relationList.add(relation);
        }
        boolean b = roleResourceRelationService.saveBatch(relationList);
        Asserts.isFalse(b, "资源分配失败");
        umsCacheService.delResourceListByRole(roleId);
    }
}
